#include "UserInterface.h"

UserInterface::UserInterface(MemoryManager* memoryManager)
{
	m_MemoryManager = memoryManager;
}

UserInterface::~UserInterface(void)
{
}

void UserInterface::start()
{
	bool exit = false;
	int junkMail = 0;

	cout << "Welcome to our nice Shell!" << endl;
	cout << "cmd: ";
	cout.flush();
	while(!exit)
	{
		char buffer[MAXLENGTH];
		int count = read(0,buffer,MAXLENGTH);

		buffer[count-1] = 0;

		//translate buffer into string for manipulation
		string input(buffer);

		//get first command
		string cmd = input.substr(0,input.find_first_of(" ",0));
		//cut the first command from input
		input = input.substr(input.find_first_of(" ",0)+1,input.size() - cmd.size());

		bool validCmd = true;
		//CreateNet  Filename
		if(!cmd.compare("createProcess") || !cmd.compare("CP"))
		{
			if (validCmd){
				int pid = m_MemoryManager->createProcess();
				if(pid > -1)
				{
					cout << "Proccess " << pid << " was created" << endl;
				}
				else
				{
					cout << "insufficient space" << endl;
				}
			}
			else{
				printf("USAGE: createProcess\n");
			}
		}
		else if(!cmd.compare("delProcess") || !cmd.compare("DP"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0)
			{
				validCmd = false;	
			}
			if (validCmd)
			{
				if(m_MemoryManager->deleteProcess(atoi(arg0.c_str())))
				{
					printf("OK\n");
				}
				else
				{
					printf("No such PID!\n");
				}
			}
			else
			{
				printf("USAGE: delProcess <pid>\n");
			}
		}
		else if(!cmd.compare("switchTo") || !cmd.compare("ST"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0)
			{
				validCmd = false;	
			}
			if (validCmd)
			{
				if(m_MemoryManager->contextSwitch(atoi(arg0.c_str())))
				{
					printf("Context switched to: %d\n", atoi(arg0.c_str()));
				}
				else
				{
					printf("No such PID!\n");
				}
			}
			else
			{
				printf("USAGE: switchTo <pid>\n");
			}
		}
		else if(!cmd.compare("write") || !cmd.compare("w"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0){
				validCmd = false;	
			}
			string arg1 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg1.size());
			if (arg1.compare("")==0 || arg1.compare(" ")==0 || arg1.compare("\n")==0){
				validCmd = false;	
			}
			if (validCmd){
				m_MemoryManager->write(atoi(arg0.c_str()), arg1.c_str());
				printf("OK\n");
			}
			else{
				printf("USAGE: write <vAddrl> <s>\n");
			}
		}
		else if(!cmd.compare("read") || !cmd.compare("r"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0){
				validCmd = false;	
			}
			string arg1 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg1.size());
			if (arg1.compare("")==0 || arg1.compare(" ")==0 || arg1.compare("\n")==0){
				validCmd = false;	
			}
			if (validCmd){
				printf("read: %s\n", m_MemoryManager->read(atoi(arg0.c_str()), atoi(arg1.c_str())));
			}
			else{
				printf("USAGE: read <vAddrl> <ammount>\n");
			}		
		}
		else if(!cmd.compare("loopRead") || !cmd.compare("lr"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0){
				validCmd = false;	
			}
			string arg1 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg1.size());
			if (arg1.compare("")==0 || arg1.compare(" ")==0 || arg1.compare("\n")==0){
				validCmd = false;	
			}
			string arg2 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg2.size());
			if (arg2.compare("")==0 || arg2.compare(" ")==0 || arg2.compare("\n")==0){
				validCmd = false;	
			}
			if (validCmd){
				int vAddr = atoi(arg0.c_str());
				int off = atoi(arg1.c_str());
				int ammount = atoi(arg2.c_str());

				for(int i=0;i<ammount;i++)
				{
					printf("loopRead %d: %s\n", i+1, m_MemoryManager->read(vAddr+(i*off), 1));
				}
			}
			else{
				printf("USAGE: loopRead <vAddr> <off> <ammount>\n");
			}		
		}
		else if(!cmd.compare("loopWrite") || !cmd.compare("lw"))
		{
			string arg0 = input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg0.size());
			if (arg0.compare("")==0 || arg0.compare(" ")==0 || arg0.compare("\n")==0){
				validCmd = false;	
			}
			string arg1 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg1.size());
			if (arg1.compare("")==0 || arg1.compare(" ")==0 || arg1.compare("\n")==0){
				validCmd = false;	
			}
			string arg2 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg2.size());
			if (arg2.compare("")==0 || arg2.compare(" ")==0 || arg2.compare("\n")==0){
				validCmd = false;	
			}
			string arg3 =  input.substr(0,input.find_first_of(" ",0));
			input = input.substr(input.find_first_of(" ",0)+1,input.size() - arg3.size());
			if (arg3.compare("")==0 || arg3.compare(" ")==0 || arg3.compare("\n")==0){
				validCmd = false;	
			}
			if (validCmd){
				int vAddr = atoi(arg0.c_str());
				const char* c = arg1.c_str();
				int off = atoi(arg2.c_str());
				int ammount = atoi(arg3.c_str());

				for(int i=0;i<ammount;i++)
				{
					m_MemoryManager->write(vAddr+(i*off), c);
				}
				printf("OK\n");
			}
			else{
				printf("USAGE: loopRead <vAddr> <off> <ammount>\n");
			}		
		}
		else if(!cmd.compare("userHitRate") || !cmd.compare("UHR"))
		{
			printf("userHitRate: %f\n", m_MemoryManager->getUserHitRate());
		}
		else if(!cmd.compare("kernelHitRate") || !cmd.compare("KHR"))
		{
			printf("kernelHitRate: %f\n", m_MemoryManager->getKernelHitRate());
		}
		else if(!cmd.compare("printUserMM") || !cmd.compare("PUMM"))
		{
			m_MemoryManager->printUserMM();
		}
		else if(!cmd.compare("printKernelMM") || !cmd.compare("PKMM"))
		{
			m_MemoryManager->printKernelMM();
		}
		else if(!cmd.compare("printMMUTable") || !cmd.compare("PMMUT"))
		{
			m_MemoryManager->printMMUTable();
		}
		//Exit
		else if(!cmd.compare("Exit"))
		{
			if (validCmd){
				exit = true;
				//shell->m_system->stop();
				printf("Bye...Bye...!\n");
			}
			else{
				printf("USAGE: Exit\n");
			}
		}
		else
		{
			printf("Wrong Command - Try again...\n");
		}

		if(!exit)
		{
			cout << "cmd: ";
			cout.flush();
		}
	}
	
}
